package goim

import (
	"bufio"
	"net"

	"gitee.com/zhangxinzx/im-related/pkg/encoding/binary"
)

//Encoder interface implementaion assertion
var _ Encoder = (*encoder)(nil)

type Encoder interface {
	Write(p *Proto) error
}

type encoder struct {
	writer *bufio.Writer
}

func NewGoimEncoder(conn net.Conn) Encoder {
	return &encoder{writer: bufio.NewWriter(conn)}
}

func (enc *encoder) Write(p *Proto) error {
	var (
		buf     []byte = make([]byte, _rawHeaderSize)
		packLen int32
		err     error
	)

	packLen = _rawHeaderSize + int32(len(p.Body))
	binary.BigEndian.PutInt32(buf[_packOffset:], packLen)
	binary.BigEndian.PutInt16(buf[_headerOffset:], int16(_rawHeaderSize))
	binary.BigEndian.PutInt16(buf[_verOffset:], int16(p.Ver))
	binary.BigEndian.PutInt32(buf[_opOffset:], int32(p.Op))
	binary.BigEndian.PutInt32(buf[_seqOffset:], p.Seq)

	_, err = enc.writer.Write(buf)

	if p.Body != nil {
		_, err = enc.writer.Write(p.Body)

	}

	enc.writer.Flush()

	return err
}
